<?php


namespace GordenSong\Support;



use GordenSong\Utils\RuleUtil;

trait ValidatorTrait
{
	/** @var array */
	protected $attributes = [];
	/** @var array */
	protected $messages = [];
	/** @var array */
	protected $rules = [];

	public function attributes(): array
	{
		return $this->attributes;
	}

	public function rules(): array
	{
		return $this->rules;
	}

	public function messages(): array
	{
		return $this->messages;
	}

	/**
	 * @param array $attributes
	 */
	public function setAttributes(array $attributes): void
	{
		$this->attributes = $attributes;
	}

	/**
	 * @param array $messages
	 */
	public function setMessages(array $messages): void
	{
		$this->messages = $messages;
	}

	/**
	 * overwrite rules
	 * @param array $rules
	 */
	public function setRules(array $rules)
	{
		$this->rules = RuleUtil::normalizeManyRules($rules);
	}

	/**
	 * 定制的规则
	 * @return array
	 */
	public function customizeRules(): array
	{
		return [];
	}

	/**
	 * 要排除的规则
	 * @return array
	 */
	public function excludeRules(): array
	{
		return [];
	}

	public function addRules(array $rules)
	{
		foreach ($rules as $key => $rule) {
			$this->addRule($key, $rule);
		}

		return $this;
	}

	/**
	 * @param string $key
	 * @param array $rules
	 */
	public function addRule(string $key, array $rules)
	{
		$thisRules = data_get($this->rules, $key, []);

		$this->rules[$key] = array_values(RuleUtil::mergeRules($thisRules, $rules));

		return $this;
	}

	/**
	 * @param string $key
	 * @return array
	 */
	public function getRule(string $key): array
	{
		return data_get($this->rules(), $key, []);
	}

	/**
	 * 排除字段
	 * @param array $rules
	 * @return $this
	 */
	public function exclude(array $rules)
	{
		$this->rules = RuleUtil::diffManyRules($this->rules(), $rules);

		return $this;
	}

	/**
	 * @param string $field
	 * @return bool
	 */
	public function hasKey(string $field): bool
	{
		return array_key_exists($field, $this->rules);
	}

	public function only(...$fields)
	{
		if (func_num_args() == 0) {
			return $this;
		}

		$field = func_get_arg(0);
		$fields = is_array($field) ? $field : $fields;

		$rules = [];
		foreach ($fields as $field) {
			$rule = $this->getRule($field);
			if ($rule) {
				$rules[$field] = $rule;
			}
		}
		$this->rules = $rules;

		return $this;
	}
}